/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using System.Qizx.Api.Util;
using DataModelException = System.Qizx.Api.DataModelException;
using EvaluationException = System.Qizx.Api.EvaluationException;
using ItemType = System.Qizx.Api.ItemType;
using Node = System.Qizx.Api.Node;
using XQDate = System.Qizx.Api.Util.XQDate;
using DateTime = System.Qizx.Api.Util.XQDateTime;
using DateTimeException = System.Qizx.Api.Util.XQDateTimeException;
using BaseValue = System.Qizx.XQuery.BaseValue;
using ComparisonContext = System.Qizx.XQuery.ComparisonContext;
using XQItem = System.Qizx.XQuery.XQItem;
using XQItemType = System.Qizx.XQuery.XQItemType;
using XQType = System.Qizx.XQuery.XQType;
using XQValue = System.Qizx.XQuery.XQValue;
using SingleString = System.Qizx.XQuery.Dt.SingleString;
using UntypedAtomicType = System.Qizx.XQuery.Dt.UntypedAtomicType;
namespace System.Qizx.Xdm {

    public abstract class NodeSequenceBase : BaseValue {
        public class EmptyNodeSequenceBase : NodeSequenceBase {
            public override bool Next() {
                return false;
            }

            public override BasicNode GetBasicNode() {
                return null;
            }

            public override XQValue BornAgain() {
                return null;
            }
        }
        public override ItemType ValueType {
            get {
                return XQType.NODE;
            }

        }
        public override XQItemType ItemType {
            get {
                return XQType.NODE;
            }

        }
        public override XQItem Item {
            get {
                return GetBasicNode();
            }

        }
        public override bool ValueAsBoolean {
            get {
                return true;
            }

        }
        public override string ValueAsString {
            get {
                try {
                    return GetNode().StringValue;
                } catch (DataModelException e) {
                    throw BasicNode.WrapDMException(e);
                }
            }

        }
        public override long ValueAsInteger {
            get {
                return Conversion.toInteger(ValueAsString);
            }

        }
        public override double ValueAsDouble {
            get {
                try {
                    return Conversion.toDouble(ValueAsString);
                } catch (EvaluationException e) {
                    double v = ((BasicNode)GetNode()).DoubleByRules;
                    if (v == v)
                        // successful
                        return v;
                    throw e;
                }
            }

        }
        public override float ValueAsFloat {
            get {
                try {
                    return Conversion.toFloat(ValueAsString);
                } catch (EvaluationException e) {
                    double v = ((BasicNode)GetNode()).DoubleByRules;
                    if (v == v)
                    // successful
					{
                        return (float)v;
                    }
                    throw e;
                }
            }

        }
        public override XQDate ValueAsDate {
            get {
                return GetBasicNode().ValueAsDate;
            }

        }
        public override XQDateTime ValueAsDateTime {
            get {
                return GetBasicNode().ValueAsDateTime;
            }

        }
        public static readonly NodeSequenceBase noNodes;

        public override bool IsNode {
            get { return true; }
        }

        public override Node GetNode() {
            return GetBasicNode();
        }

        public abstract override BasicNode GetBasicNode();

        public override XQItem AsAtom() {
            // this is OK for Basic XQ: improve it later
            try {
                return new SingleString(GetNode().StringValue, XQType.UNTYPED_ATOMIC);
            } catch (DataModelException e) {
                throw BasicNode.WrapDMException(e);
            }
        }

        public override int CompareTo(XQItem that, ComparisonContext context, int flags) {
            return UntypedAtomicType.comparison(this, that, context, flags);
        }
        static NodeSequenceBase() {
            noNodes = new EmptyNodeSequenceBase();
        }
    }
}